package com.lpf;

import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import java.io.IOException;
import java.util.List;

/**
 * ElasticSearch 还提供了一套 Query DSL 语言帮助我们构造复杂的查询条件，查询条件主要分为下面两部分：
 *
 * Leaf 子句：Leaf 子句一般是针对某个字段的查询，例如：
 *    Match Query：最常用的 Full Text Query 。Match Query 既能处理全文字段，又能处理精确字段。
 *    Term Query：精确匹配字段值的查询。
 *    Range Query：针对一个字段的范围查询。
 * Compound 子句：Conpound 子句是由一个或多个 Leaf 子句或 Compound 子句构成的，例如 Bool Query，包含多个返回 Boolean 值的子句。
 *
 *
 */
public class Main08 {

    public static void main(String[] args) throws IOException {

        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("localhost", 9200, "http"),
                        new HttpHost("localhost", 9200, "http")
                )
        );

        // 创建 SearchRequest 请求，查询的 Index 为 skywalking
        SearchRequest searchRequest = new SearchRequest("skywalking");
        // 通过 SearchSourceBuilder，用来构造检索条件
        SearchSourceBuilder sourceBuilder = SearchSourceBuilder.searchSource();
        // 创建 BoolQueryBuilder
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        // 符合条件的 Document 中 age 字段的值必须位于[10,40]这个范围
        List<QueryBuilder> mustQueryList = boolQueryBuilder.must();
        mustQueryList.add(QueryBuilders.rangeQuery("age").gte(10));
        mustQueryList.add(QueryBuilders.rangeQuery("age").lte(40));

        // 符合条件的 Document 中 user 字段的值必须为 kim
        boolQueryBuilder.must().add(QueryBuilders.termQuery("user", "kim"));

        sourceBuilder.query(boolQueryBuilder);
        searchRequest.source(sourceBuilder);

        // 发送 SearchRequest 请求
        SearchResponse searchResponse = client.search(searchRequest);
        SearchHit[] searchHits = searchResponse.getHits().getHits();

        for (SearchHit searchHit : searchHits) {
            System.out.println(searchHit.getId() + ":" + searchHit.getSourceAsMap());
        }
    }
}